package com.mouse.multi.service;

import com.mouse.multi.entity.model.NovelInfo;
import com.mouse.multi.entity.model.NovelWeb;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class NovelWebService {
    private final int JSOUP_MAX_SIZE = 5 * 1024 * 1024;

    public static void main(String[] args) throws Exception {
        NovelWeb novelWeb = new NovelWeb();
        novelWeb.setWebUrl("http://chuangshi.qq.com/bk/ds/AG0ENl1gVjYAPlRi-l.html?sword=%E6%9E%81%E5%93%81%E5%85%A8%E8%83%BD%E5%AD%A6%E7%94%9F");
        novelWeb.setOutSelect("div[class=list]");
        novelWeb.setOutFlag(2);
        novelWeb.setOutContent("新书感言");
        novelWeb.setInSelect("a");
        novelWeb.setInFlag(0);
        novelWeb.setUrlFlag(1);
        novelWeb.setUrlContent("href");
        novelWeb.setTitleFlag(0);
        novelWeb.setTimeFlag(2);
        novelWeb.setTimeContent("更新时间：([ -:0-9]+)");
        novelWeb.setSort(1);
        novelWeb.setSize(10);
        List<NovelInfo> list = new NovelWebService().filter(novelWeb);
        System.out.println(list);
    }

    public List<NovelInfo> filter(NovelWeb novelWeb) throws Exception {
        //http get访问
        Document htmlDocument = Jsoup.connect(novelWeb.getWebUrl()).maxBodySize(JSOUP_MAX_SIZE).get();
        //外层css选择
        Elements outElements = htmlDocument.select(novelWeb.getOutSelect());
        //外层过滤
        elementFilter(outElements, novelWeb.getOutFlag(), novelWeb.getOutContent());
        //外层选择遍历
        List<NovelInfo> resultList = new ArrayList<>();
        sizeFlag:
        for (int i = 0; i < outElements.size(); i++) {
            //顺序 倒序
            int outIndex = novelWeb.getSort() == 1 ? outElements.size() - i - 1 : i;
            Element outElement = outElements.get(outIndex);
            //内层css选择
            Elements inElements = outElement.select(novelWeb.getInSelect());
            //内层过滤
            elementFilter(inElements, novelWeb.getInFlag(), novelWeb.getInContent());
            //内容初始化
            for (int j = 0; j < inElements.size(); j++) {
                //顺序 倒序
                int inIndex = novelWeb.getSort() == 1 ? inElements.size() - j - 1 : j;
                Element inElement = inElements.get(inIndex);
                NovelInfo novelInfo = new NovelInfo();
                resultList.add(novelInfo);
                novelInfo.setWebId(novelWeb.getId());
                //筛选标题
                novelInfo.setTitle(contentSelect(inElement, novelWeb.getTitleFlag(), novelWeb.getTitleContent()));
                //筛选url
                novelInfo.setUrl((novelWeb.getBaseUrl() == null ? "" : novelWeb.getBaseUrl())
                        + contentSelect(inElement, novelWeb.getUrlFlag(), novelWeb.getUrlContent()));
                //筛选时间
                novelInfo.setCreateTime(contentSelect(inElement, novelWeb.getTimeFlag(), novelWeb.getTimeContent()));
                //小说章数
                if (novelWeb.getSize() != null && resultList.size() >= novelWeb.getSize()) {
                    break sizeFlag;
                }
            }
        }
        return resultList;
    }

    private void elementFilter(Elements elements, Integer flag, String content) {
        for (int i = elements.size() - 1; i >= 0; i--) {
            Element outElement = elements.get(i);
            String outHtml = outElement.toString();
            if (flag == 1) {//包含标识
                if (outHtml.indexOf(content) == -1) {
                    elements.remove(i);
                }
            } else if (flag == 2) {//不包含标识
                if (outHtml.indexOf(content) > -1) {
                    elements.remove(i);
                }
            } else {//无
            }
        }
    }

    private String contentSelect(Element inElement, Integer flag, String content) {
        String resultContent = "";
        if (flag == null) {//内容提取
            resultContent = null;
        } else if (flag == 0) {//内容提取
            resultContent = inElement.text();
        } else if (flag == 1) {//属性提取
            resultContent = inElement.attr(content);
        } else if (flag == 2) {//正则表达式提取
            Pattern pattern = Pattern.compile(content);
            Matcher matcher = pattern.matcher(inElement.toString());
            while (matcher.find()) {
                resultContent = matcher.group(1);
            }
        }
        return resultContent;
    }
}
